package ynu.edu.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ynu.edu.constant.PaymentConstant;
import ynu.edu.dto.PaymentDTO;
import ynu.edu.dto.PaymentRequest;
import ynu.edu.entities.BaseResponse;
import ynu.edu.entities.Order;
import ynu.edu.entity.PaymentEntity;
import ynu.edu.exception.PaymentException;
import ynu.edu.feign.OrderServiceClient;
import ynu.edu.repository.PaymentRepository;
import ynu.edu.service.PaymentService;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 支付服务实现类
 */
@Slf4j
@Service
public class PaymentServiceImpl implements PaymentService {
    
    private final PaymentRepository paymentRepository;
    private final OrderServiceClient orderServiceClient;
    
    public PaymentServiceImpl(PaymentRepository paymentRepository, OrderServiceClient orderServiceClient) {
        this.paymentRepository = paymentRepository;
        this.orderServiceClient = orderServiceClient;
    }
    
    @Override
    @Transactional
    public PaymentDTO createPayment(PaymentRequest request) {
        log.info("创建支付订单：{}", request);
        
        // 查询订单信息
        BaseResponse<Order> orderResponse = orderServiceClient.getOrderById(request.getOrderId());
        if (orderResponse.getCode() != 200 || orderResponse.getData() == null) {
            log.error("订单不存在，订单ID：{}", request.getOrderId());
            throw new PaymentException("订单不存在");
        }
        
        Order order = orderResponse.getData();
        
        // 检查订单状态
        if (order.getOrderState() != 0) {
            log.error("订单状态异常，无法支付，订单ID：{}，订单状态：{}", request.getOrderId(), order.getOrderState());
            throw new PaymentException("订单状态异常，无法支付");
        }
        
        // 检查是否已存在支付记录
        Optional<PaymentEntity> existingPayment = paymentRepository.findByOrderId(request.getOrderId());
        if (existingPayment.isPresent()) {
            log.info("订单已存在支付记录，订单ID：{}", request.getOrderId());
            PaymentEntity paymentEntity = existingPayment.get();
            
            if (paymentEntity.getStatus().equals(PaymentConstant.STATUS_PAID)) {
                throw new PaymentException("订单已支付，请勿重复支付");
            }
            
            // 如果是已取消的支付，重新创建
            if (paymentEntity.getStatus().equals(PaymentConstant.STATUS_CANCELLED)) {
                paymentEntity.setStatus(PaymentConstant.STATUS_UNPAID);
                paymentEntity.setPaymentType(request.getPaymentType());
                paymentEntity.setUpdateTime(LocalDateTime.now());
                PaymentEntity savedPayment = paymentRepository.save(paymentEntity);
                return convertToDTO(savedPayment);
            }
            
            // 如果是未支付的，返回已有记录
            return convertToDTO(paymentEntity);
        }
        
        // 创建新的支付记录
        PaymentEntity paymentEntity = new PaymentEntity();
        paymentEntity.setOrderId(request.getOrderId());
        paymentEntity.setUserId(request.getUserId());
        paymentEntity.setAmount(request.getAmount());
        paymentEntity.setStatus(PaymentConstant.STATUS_UNPAID);
        paymentEntity.setPaymentType(request.getPaymentType());
        paymentEntity.setCreateTime(LocalDateTime.now());
        paymentEntity.setUpdateTime(LocalDateTime.now());
        
        PaymentEntity savedPayment = paymentRepository.save(paymentEntity);
        log.info("支付订单创建成功：{}", savedPayment);
        
        return convertToDTO(savedPayment);
    }
    
    @Override
    @Transactional
    public PaymentDTO processPayment(Integer paymentId, String transactionId) {
        log.info("处理支付，支付ID：{}，交易号：{}", paymentId, transactionId);
        
        // 查询支付记录
        PaymentEntity payment = getPaymentEntity(paymentId);
        
        // 检查支付状态
        if (payment.getStatus().equals(PaymentConstant.STATUS_PAID)) {
            log.error("订单已支付，请勿重复支付，支付ID：{}", paymentId);
            throw new PaymentException("订单已支付，请勿重复支付");
        }
        
        if (payment.getStatus().equals(PaymentConstant.STATUS_CANCELLED)) {
            log.error("支付已取消，无法完成支付，支付ID：{}", paymentId);
            throw new PaymentException("支付已取消，无法完成支付");
        }
        
        // 更新支付状态
        payment.setStatus(PaymentConstant.STATUS_PAID);
        payment.setPaymentTime(LocalDateTime.now());
        payment.setTransactionId(transactionId);
        payment.setUpdateTime(LocalDateTime.now());
        PaymentEntity updatedPayment = paymentRepository.save(payment);
        
        // 更新订单状态 - 使用POST方法
        try {
            BaseResponse<Void> updateResult = orderServiceClient.updateOrderStatePost(payment.getOrderId(), 2);
            if (updateResult.getCode() != 200) {
                log.error("使用POST方法更新订单状态失败，订单ID：{}", payment.getOrderId());
                // 尝试使用PUT方法
                updateResult = orderServiceClient.updateOrderState(payment.getOrderId(), 2);
                if (updateResult.getCode() != 200) {
                    log.error("使用PUT方法更新订单状态也失败，订单ID：{}", payment.getOrderId());
                    throw new PaymentException("支付成功，但更新订单状态失败");
                }
            }
        } catch (Exception e) {
            log.error("调用订单服务更新状态异常：", e);
            throw new PaymentException("支付成功，但更新订单状态失败：" + e.getMessage());
        }
        
        log.info("支付成功：{}", updatedPayment);
        return convertToDTO(updatedPayment);
    }
    
    @Override
    @Transactional
    public PaymentDTO cancelPayment(Integer paymentId) {
        log.info("取消支付，支付ID：{}", paymentId);
        
        // 查询支付记录
        PaymentEntity payment = getPaymentEntity(paymentId);
        
        // 检查支付状态
        if (payment.getStatus().equals(PaymentConstant.STATUS_PAID)) {
            log.error("订单已支付，无法取消，支付ID：{}", paymentId);
            throw new PaymentException("订单已支付，无法取消");
        }
        
        if (payment.getStatus().equals(PaymentConstant.STATUS_CANCELLED)) {
            log.info("支付已取消，无需再次取消，支付ID：{}", paymentId);
            return convertToDTO(payment);
        }
        
        // 更新支付状态
        payment.setStatus(PaymentConstant.STATUS_CANCELLED);
        payment.setUpdateTime(LocalDateTime.now());
        PaymentEntity updatedPayment = paymentRepository.save(payment);
        
        log.info("支付取消成功：{}", updatedPayment);
        return convertToDTO(updatedPayment);
    }
    
    @Override
    public PaymentDTO getPayment(Integer paymentId) {
        log.info("查询支付信息，支付ID：{}", paymentId);
        PaymentEntity payment = getPaymentEntity(paymentId);
        return convertToDTO(payment);
    }
    
    @Override
    @Transactional
    public PaymentDTO paySuccess(Integer paymentId) {
        log.info("支付成功处理，支付ID：{}", paymentId);
        // 生成随机交易号
        String transactionId = UUID.randomUUID().toString().replaceAll("-", "");
        log.info("生成交易号：{}", transactionId);
        // 调用处理支付的方法
        return processPayment(paymentId, transactionId);
    }
    
    @Override
    public PaymentDTO getPaymentByOrderId(Integer orderId) {
        log.info("根据订单ID查询支付信息，订单ID：{}", orderId);
        
        Optional<PaymentEntity> payment = paymentRepository.findByOrderId(orderId);
        if (!payment.isPresent()) {
            log.error("支付记录不存在，订单ID：{}", orderId);
            throw new PaymentException("支付记录不存在");
        }
        
        return convertToDTO(payment.get());
    }
    
    @Override
    public List<PaymentDTO> getUserPayments(String userId) {
        log.info("查询用户支付记录，用户ID：{}", userId);
        
        List<PaymentEntity> payments = paymentRepository.findByUserId(userId);
        return payments.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    @Override
    public List<PaymentDTO> getUserPaymentsByStatus(String userId, Integer status) {
        log.info("查询用户支付记录，用户ID：{}，状态：{}", userId, status);
        
        List<PaymentEntity> payments = paymentRepository.findByUserIdAndStatus(userId, status);
        return payments.stream().map(this::convertToDTO).collect(Collectors.toList());
    }
    
    /**
     * 根据ID获取支付实体
     *
     * @param paymentId 支付ID
     * @return 支付实体
     */
    private PaymentEntity getPaymentEntity(Integer paymentId) {
        Optional<PaymentEntity> payment = paymentRepository.findById(paymentId);
        if (!payment.isPresent()) {
            log.error("支付记录不存在，支付ID：{}", paymentId);
            throw new PaymentException("支付记录不存在");
        }
        return payment.get();
    }
    
    /**
     * 将实体转换为DTO
     *
     * @param entity 支付实体
     * @return 支付DTO
     */
    private PaymentDTO convertToDTO(PaymentEntity entity) {
        PaymentDTO dto = new PaymentDTO();
        BeanUtils.copyProperties(entity, dto);
        return dto;
    }
} 